package com.luodim.dialogtest;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Random;

/**
 * Created by luodi on 2017/6/22.
 * the BaseUtils class contains some common methods
 */

public class BaseUtils {

    public static final String TAG = "edwin";
    private static final Bitmap.Config CONFIG = Bitmap.Config.ARGB_4444;
    private static int mOri = -1;
    private static DeviceParams mParams = new DeviceParams();

    /**
     * 拼接多张相同bitmap为一张大的bitmap
     * @param context
     * @param resId 需拼接的资源id
     * @param count 拼接数量
     * @param isPortrait 拼接方向
     *                   true: 竖直拼接 false: 横向拼接
     * @return 拼接后的bitmap对象
     */
    public static Bitmap spliceSameBitmaps(@NonNull Context context, int resId, int count, boolean isPortrait) {
        if (context == null) return null;
        Bitmap tempBmp = BitmapFactory.decodeResource(context.getResources(), resId);
        return spliceSameBitmaps(context, tempBmp, count, isPortrait);
    }

    /**
     * 拼接多张相同bitmap为一张大的bitmap
     * @param context
     * @param bitmap 需拼接的bitmap对象
     * @param count 拼接数量
     * @param isPortrait 拼接方向
     *                   true: 竖直拼接 false: 横向拼接
     * @return 拼接后的bitmap对象
     */
    public static Bitmap spliceSameBitmaps(@NonNull Context context, Bitmap bitmap, int count, boolean isPortrait) {
        if (context == null || bitmap == null) return null;
        float leftPos = 0;
        float topPos = 0;

        Bitmap tempBmp = bitmap;

        int totalWidth = isPortrait ? tempBmp.getWidth() : tempBmp.getWidth() * count;
        int totalHeight = isPortrait ? tempBmp.getHeight() * count : tempBmp.getHeight();

        Bitmap resultBmp = Bitmap.createBitmap(totalWidth, totalHeight, CONFIG);
        Canvas canvas = new Canvas(resultBmp);
        while (count > 0) {
            canvas.drawBitmap(tempBmp, leftPos, topPos, null);
            leftPos += isPortrait ? 0 : tempBmp.getWidth();
            topPos += isPortrait ? tempBmp.getHeight() : 0;
            count --;
        }
        tempBmp.recycle();
        return resultBmp;
    }

    /**
     * 对bitmap进行压缩/裁剪
     * @param context
     * @param resId 需被压缩/裁剪的资源id
     * @param scale 需要压缩的比例。scale为PointF对象，包含x,y两个数值，代表横向及纵向压缩比例
     * @param cutRatio 需要裁剪的比例。cutRatio为RectF对象，包含左上右下4个参数，代表左上右下各方向的被裁剪区域占原bitmap矩形区域的比例
     * @return 处理后的bitmap对象
     */
    public static Bitmap bitmapSizeFit(@NonNull Context context, int resId, PointF scale, RectF cutRatio) {
        if (context == null) return null;
        Bitmap tempBmp = BitmapFactory.decodeResource(context.getResources(), resId);
        return bitmapSizeFit(context, tempBmp, scale, cutRatio);
    }

    /**
     * 对bitmap进行压缩/裁剪
     * @param context
     * @param bmp 需被压缩/裁剪的bitmap对象
     * @param scale 需要压缩的比例。scale为PointF对象，包含x,y两个数值，代表横向及纵向压缩比例
     * @param cutRatio 需要裁剪的比例。cutRatio为RectF对象，包含左上右下4个参数，代表左上右下各方向的被裁剪区域占原bitmap矩形区域的比例
     * @return 处理后的bitmap对象
     */
    public static Bitmap bitmapSizeFit(@NonNull Context context, Bitmap bmp, PointF scale, RectF cutRatio) {
        if (context == null || bmp == null) return null;

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;
        options.inPreferredConfig = CONFIG;
        options.inJustDecodeBounds = false;

        Bitmap tempBmp = bmp;

        PointF scaleF = scale == null ? new PointF(1, 1) : scale;
        RectF cutRatioF = cutRatio == null ? new RectF() : cutRatio;

        //裁剪逻辑，cuRatio设置入了左上右下4边各边的被裁减区域占原矩形区域的百分比
        int x = (int) (tempBmp.getWidth() * cutRatioF.left);
        int y = (int) (tempBmp.getHeight() * cutRatioF.top);
        int width = (int) (tempBmp.getWidth() - tempBmp.getWidth() * cutRatioF.right - x);
        int height = (int) (tempBmp.getHeight() - tempBmp.getHeight() * cutRatioF.bottom - y);

        //缩放逻辑
        float bmpHeight = getDeviceHeight(context) * scaleF.y;
        float scaleRatio = bmpHeight / height;

        Matrix matrix = new Matrix();
        matrix.postScale(scaleRatio, scaleRatio);

        return Bitmap.createBitmap(tempBmp, x, y, width, height, matrix, true);
    }

    public static Bitmap rotateBitmap(Context context, int resId, float degree) {
        if (context == null) return null;
        Bitmap tempBmp = BitmapFactory.decodeResource(context.getResources(), resId);
        return rotateBitmap(context, tempBmp, degree);
    }

    public static Bitmap rotateBitmap(Context context, Bitmap bmp, float degree) {
        if (context == null || bmp == null) return null;
        int w = bmp.getWidth();
        int h = bmp.getHeight();
        Bitmap resultBmp = Bitmap.createBitmap(w, h, CONFIG);
        Canvas canvas = new Canvas(resultBmp);

        Matrix matrix = new Matrix();
        matrix.postRotate(degree, w * 1.0f / 2, h * 1.0f / 2);
        Bitmap tempBmp = Bitmap.createBitmap(bmp, 0, 0, w, h, matrix, true);

        canvas.drawBitmap(tempBmp, 0, 0, null);

        return resultBmp;
    }

    public static Bitmap getImageBitmap(String url) {
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
        } catch (Exception e) {
            Log.e(TAG, "Error getting bitmap", e);
        }
        return bm;
    }

    /**
     * 获取基本设备信息
     * @return DeviceParams对象
     */
    public static DeviceParams getDevicesInfo(Context context) {
        if (context == null) return null;
        Configuration config = context.getResources().getConfiguration();

        if (mOri == -1 || mOri != config.orientation) {
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics metrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(metrics);
            mParams.deviceWidth = metrics.widthPixels;
            mParams.deviceHeight = metrics.heightPixels;
            mParams.deviceDensity = metrics.density;
            mParams.deviceDpi = metrics.densityDpi;
            mOri = config.orientation;
        }
        return mParams;
    }

    /**
     * 获取设备屏幕宽度
     * @return 屏幕宽度，单位为pixel
     */
    public static float getDeviceWidth(Context context) {
        DeviceParams params = getDevicesInfo(context);
        if (params == null) return -1;
        return params.deviceWidth;
    }

    /**
     * 获取设备屏幕高度
     * @return 屏幕高度，单位为pixel
     */
    public static float getDeviceHeight(Context context) {
        DeviceParams params = getDevicesInfo(context);
        if (params == null) return -1;
        return params.deviceHeight;
    }

    /**
     * 字符串拼接，避免通过 + 连接导致产生大量String对象
     * @param obj 用户设置的需要拼接的字符串内容
     * @return 拼接后的长字符串String对象
     */
    public static String getLongStr(Object... obj) {
        StringBuilder builder = new StringBuilder();
        for (Object o : obj) {
            builder.append(o);
        }
        return builder.toString();
    }

    /**
     * dp转px
     * @param dp 需要转换的dp数值
     */
    public static float dp2px(Context context, int dp) {
        DeviceParams params = getDevicesInfo(context);
        if (params == null || params.deviceDensity <= 0) return -1;
        return dp * params.deviceDensity;
    }

    /**
     * px转dp
     * @param px 需要转换的px数值
     */
    public static float px2dp(Context context, int px) {
        DeviceParams params = getDevicesInfo(context);
        if (params == null || params.deviceDensity <= 0) return -1;
        return px / params.deviceDensity;
    }

    /**
     * int值伪随机数生成
     * @param min 生成随机数的最小值
     * @param max 生成随机数的最大值
     * @return 生成的int随机数
     */
    public static int generateRandom(int min, int max) {
        Random random = new Random();
        return random.nextInt(max - min) + min;
    }

}
